//
// @Auther: by wujehy 
// @Email:wujehy@qq.com
// @Data:2019/10/08
// @Time:9:59 上午
//

#include "mosquitto_plugin.h"
#include "mosquitto_broker.h"
#include "mosquitto.h"
#include <iostream>
#include <map>
#include "AuthPluginInterface.h"
#include "Logger.h"

int mosquitto_auth_plugin_version(void)
{
//    log_init();
//    _log(LOG_NOTICE, "*** auth-plug: startup");
    std::cerr<<" Auth : startup "<<std::endl;
    return MOSQ_AUTH_PLUGIN_VERSION;
}


/**
 * @brief 插件初始化
 * @param user_data 储存上下文指针
 * @param opts 配置
 * @param opt_count 配置信息数量
 * @return
 */
int mosquitto_auth_plugin_init(void **user_data, struct mosquitto_opt *auth_opts, int auth_opt_count)
{

    std::cout <<" test init " <<std::endl;
    gDebug<<"mosquitto_auth_plugin_init ";
    // 选择需要实例的对象
    AuthPluginInterface *authPlugin = AuthPluginInterface::New();
    struct mosquitto_opt *o;
    int i = 0 ;


    for ( i = 0, o = auth_opts; i < auth_opt_count; i++, o++)
    {
        if ( authPlugin->AddConfig(o->key , o->value)){
            // ok
        } else
        {
            // false
        }
    }
    *user_data = authPlugin;
    authPlugin->init();
    return MOSQ_ERR_SUCCESS;
}

/**
 * @brief 插件反初始化
 * @param user_data 上下文指针
 * @param opts
 * @param opt_count
 * @return
 */
int mosquitto_auth_plugin_cleanup(void *user_data, struct mosquitto_opt *auth_opts, int auth_opt_count)
{
    std::cerr <<"mosquitto_auth_plugin_cleanup "<<std::endl;

    AuthPluginInterface *authPlugin = nullptr;
    if (user_data!= nullptr)
    {
        authPlugin = (AuthPluginInterface*)user_data;
        delete authPlugin;
    }else
    {
        // plugin 为空
    }

    return MOSQ_ERR_SUCCESS;
}


int mosquitto_auth_security_init(void *user_data, struct mosquitto_opt *auth_opts, int auth_opt_count, bool reload)
{
//    std::cerr <<" mosquitto_auth_security_init reload = " << reload <<std::endl;
//    return MOSQ_ERR_SUCCESS;

    AuthPluginInterface *authPlugin = nullptr;
    if (user_data != nullptr)
    {
        authPlugin = (AuthPluginInterface*)user_data;

        return authPlugin->initSecurity(auth_opts , auth_opt_count , reload );
    } else
    {
        return MOSQ_ERR_UNKNOWN;
    }
}

int mosquitto_auth_security_cleanup(void *user_data, struct mosquitto_opt *auth_opts, int auth_opt_count, bool reload)
{
//    std::cerr <<" mosquitto_auth_security_cleanup reload = " << reload <<std::endl;
    AuthPluginInterface *authPlugin = nullptr;
    if (user_data != nullptr)
    {
        authPlugin = (AuthPluginInterface*)user_data;

        return authPlugin->cleanupSecurity(auth_opts , auth_opt_count , reload );
    } else
    {
        return MOSQ_ERR_SUCCESS;
    }

}
int mosquitto_auth_acl_check(void *user_data, int access, struct mosquitto *client, const struct mosquitto_acl_msg *msg){
    AuthPluginInterface *authPlugin = nullptr;
    if (user_data != nullptr)
    {
        authPlugin = (AuthPluginInterface*)user_data;

        return authPlugin->checkAcl(client , AuthPluginInterface::ACLTypeEnum(access) , msg );
    } else
    {
        return MOSQ_ERR_SUCCESS;
    }
}

int mosquitto_auth_unpwd_check(void *user_data, struct mosquitto *client, const char *username, const char *password)
{
    AuthPluginInterface *authPlugin = nullptr;
    if (user_data != nullptr)
    {
        authPlugin = (AuthPluginInterface*)user_data;

        return authPlugin->checkUser(username , password);
    } else
    {
        return MOSQ_ERR_UNKNOWN;
    }
}

int mosquitto_auth_psk_key_get(void *user_data,  struct mosquitto *client, const char *hint, const char *identity, char *key, int max_key_len)
{
    AuthPluginInterface *authPlugin = nullptr;
    if (user_data != nullptr)
    {
        authPlugin = (AuthPluginInterface*)user_data;

        return authPlugin->getPskKey(client, hint, identity,key,max_key_len);
    } else
    {
        return MOSQ_ERR_UNKNOWN;
    }
}

